package com.vgooo.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.webkit.WebView;

public class HttpUtils {
	public static final String BASE_URI = "http://www.vgooo.com/androiddata/";
	public static final int METHOD_GET = 1;
	public static final int METHOD_POST = 2;
	public static boolean needColseConn = false ;
	// jsonString 的内存软引用缓存
//	public static HashMap<String, SoftReference<String>> jsonCaches = new HashMap<String, SoftReference<String>>();

	/**
	 * 获取Http响应实体
	 * 
	 * @param urlPath
	 *            Http请求路径
	 * @param params
	 *            请求的参数
	 * @param method
	 *            请求方法
	 * @return
	 * @throws IOException
	 */
	public static HttpEntity getEntity(String urlPath,
			ArrayList<BasicNameValuePair> params, int method)
			throws IOException {
		HttpEntity entity = null;
		// 创建客户端对象
		HttpClient client = null ;
		try {
			client = new DefaultHttpClient();
			client.getParams().setParameter(
					CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
			// 创建请求对象
			HttpUriRequest request = null;
			switch (method) {
			case METHOD_GET:
				StringBuilder sb = new StringBuilder(urlPath);
				if (params != null && !params.isEmpty()) {
					sb.append('?');
					for (BasicNameValuePair pair : params) {
						sb.append(pair.getName()).append('=')
								.append(pair.getValue()).append('&');
					}
					sb.deleteCharAt(sb.length() - 1);
				}
				request = new HttpGet(sb.toString());
				break;

			case METHOD_POST:
				request = new HttpPost(urlPath);
				if (params != null && !params.isEmpty()) {
					UrlEncodedFormEntity reqEntity = new UrlEncodedFormEntity(
							params);
					((HttpPost) request).setEntity(reqEntity);
				}
				break;
			}
			// 执行请求 获得响应对象
			HttpResponse response = (HttpResponse) client.execute(request);
			// 如果响应码为200 则获得响应实体
			int code = response.getStatusLine().getStatusCode() ;
			if (code == HttpStatus.SC_OK) {
				entity = response.getEntity();
			} else {
				Log.i("HttpUtils", changeInputStream(getStream(response.getEntity())));
				throw new RuntimeException("连接网络失败：" + urlPath + "  code :" + code);
			}
		} finally{
			if(needColseConn&&client!=null){
//				ClientConnectionManager manager = client.getConnectionManager() ;
//				manager.closeExpiredConnections();
//				manager.shutdown();
//				manager = null ;
				client = null;
			}
		}
		return entity;
	}

	/**
	 * 采用GET方法获取指定地址输入流
	 * 
	 * @param urlPath
	 * @return
	 * @throws IOException
	 */
	public static InputStream getInputStream(String urlPath) throws IOException {
		InputStream inputStream = null ;
		HttpURLConnection connection = null ;
		try {
			URL url = new URL(urlPath);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(5000);
			connection.setRequestMethod("GET");
			connection.setDoInput(true);
			int code = connection.getResponseCode();
			if (code == 200) {
				inputStream = connection.getInputStream();
			} else {
				log("请求失败：" + urlPath + "地址的输入流");
				throw new RuntimeException("连接网络失败：" + urlPath);
			}
		} finally{
			if(needColseConn&&connection!=null){
				try {
//					connection.disconnect();
					connection = null ;
//					System.gc();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return inputStream ;
	}

	/**
	 * 从指定的网络路径采用GET方法获取获取Json格式字符串
	 * 
	 * @param urlPath
	 *            网络路径（绝对路径）
	 * @return
	 * @throws IOException
	 */
	public static String getJsonString(String urlPath) throws Exception {
		String jsonString = "";
		HttpURLConnection connection = null ;
		try {
			URL url = new URL(urlPath);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(5000);
			connection.setRequestMethod("GET");
			connection.setDoInput(true);
			// connection.
			int code = connection.getResponseCode();
			if (code == 200) {
				jsonString = changeInputStream(connection.getInputStream());
			} else {
				log("请求失败：" + urlPath + "地址的json字符串");
				throw new RuntimeException("连接网络失败：" + urlPath);
			}
			log("请求：" + urlPath + "地址的json字符串");
		} finally{
			if(needColseConn&&connection!=null){
				try {
//					connection.disconnect();
					connection = null ;
//					System.gc();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return jsonString;
	}

	/**
	 * 将输入流转换成字符串
	 * 
	 * @param inputStream
	 *            输入流
	 * @return
	 * @throws IOException
	 */
	public static String changeInputStream(InputStream inputStream)
			throws IOException {
		// TODO Auto-generated method stub
		String jsonString;
		byte[] data = new byte[1024];
		ByteArrayOutputStream outputStream  = null ;
		try {
			jsonString = "";
			outputStream = new ByteArrayOutputStream();
			int len = 0;

			while ((len = inputStream.read(data)) != -1) {
				outputStream.write(data, 0, len);
			}
			data = outputStream.toByteArray() ;
			jsonString = new String(data);
		} finally {
			if(data!=null){
				data = null ;
			}
			if(outputStream!=null){
				try {
					outputStream.close();
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (Exception e) {
				}
			}
			//System.gc();
		}

		return jsonString;
	}

	/**
	 * 获取Http响应实体的长度
	 * 
	 * @param entity
	 *            Http响应实体
	 * @return
	 */
	public static long getLength(HttpEntity entity) {
		if (entity != null) {
			return entity.getContentLength();
		} else {
			return 0;
		}
	}

	/**
	 * 或得响应实体的输入流
	 * 
	 * @param entity
	 *            Http响应实体
	 * @return inputStream 输入流
	 * @throws IOException
	 */
	public static InputStream getStream(HttpEntity entity) throws IOException {
		InputStream inputStream = null ;
		try {
			if (entity != null){
				inputStream =entity.getContent();
			}
		} finally{
			if(entity!=null){
				entity.consumeContent();
			}
		}
		return inputStream;
	}

	/**
	 * 从指定的网络路径获取响应实体的输入流
	 * 
	 * @param uri
	 *            网络路径
	 * @param params
	 *            请求参数
	 * @param method
	 *            请求方法
	 * @return 响应实体的输入流
	 * @throws IOException
	 */
	public static InputStream getStream(String uri,
			ArrayList<BasicNameValuePair> params, int method)
			throws IOException {
		InputStream inputStream = null ;
		HttpEntity entity = null;
		try {
			 entity =  getEntity(uri, params, method);
			inputStream =  getStream(entity);
		} finally{
			if(entity!=null){
//				entity.consumeContent();
			}
		}
		return inputStream;
	}

	/**
	 * 从指定的的网络路径获响应实体的字节数组
	 * 
	 * @param uri
	 *            网络路经
	 * @param params
	 *            请求参数
	 * @param method
	 *            请求方法
	 * @return
	 * @throws IOException
	 */
	public static byte[] getBytes(String uri,
			ArrayList<BasicNameValuePair> params, int method)
			throws Exception {
		HttpEntity entity = null;
		byte[] b = null ;
		try {
			entity = getEntity(uri, params, method);
			if (entity != null){
				b = EntityUtils.toByteArray(entity);
			}
		}  finally{
			if(entity!=null){
//				entity.consumeContent();
			}
		}
		return b;
	}
	/**
	 * 采用Post方法获取jsonString
	 * @param url 请求路径
	 * @param params  请求参数
	 * @return 获取的JSon格式数据
	 * @throws IOException
	 */
	public static String getJsonString(String url,ArrayList<BasicNameValuePair> params) throws IOException{
		return getJsonString(url, params, METHOD_POST);
	}

	/**
	 * 采用多种方法获取jsonString字符串
	 * 
	 * @param uri
	 *            请求路径
	 * @param params
	 *            请求参数
	 * @param method
	 *            请求方法
	 * @return jsonString json格式的字符串
	 * @throws IOException
	 */
	public static String getJsonString(String uri,
			ArrayList<BasicNameValuePair> params, int method)
			throws IOException {
		String jsonString = "";
		InputStream inputStream =null ;
		try {
			inputStream = getStream(uri, params, method);
			jsonString = changeInputStream(inputStream);
			log("请求：" + uri + "地址的json字符串");
		} finally{
			if(inputStream!=null){
				try {
					inputStream.close();
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
		return jsonString;

	}

	/**
	 * 采用Post方法请求参数
	 * 
	 * @param urlPath
	 * @param params
	 * @return String 结果
	 * @throws IOException
	 */
	public static String doPost(String urlPath, Map<String, String> params)
			throws IOException {
		String result = "";
		// String url = ;

		HttpClient httpclient = new DefaultHttpClient();

		HttpPost httppost = new HttpPost(urlPath);

		MultipartEntity reqEntity = new MultipartEntity();

		Set<String> keys = params.keySet();
		for (String key : keys) {
			reqEntity.addPart(key, new StringBody(params.get(key)));
		}

		// reqEntity.addPart("uid", uid);
		//
		// reqEntity.addPart("code", code);
		//
		// reqEntity.addPart("file", bin);

		httppost.setEntity(reqEntity);

		System.out.println("执行: " + httppost.getRequestLine());

		HttpResponse response = httpclient.execute(httppost);

		System.out.println("statusCode is "
				+ response.getStatusLine().getStatusCode());

		HttpEntity resEntity = response.getEntity();

		System.out.println("----------------------------------------");

		System.out.println(response.getStatusLine());

		if (resEntity != null) {

			System.out.println("返回长度: " + resEntity.getContentLength());

			System.out.println("返回类型: " + resEntity.getContentType());

			InputStream in = resEntity.getContent();

			System.out.println("in is " + in);

			// System.out.println(IoStreamUtil.getStringFromInputStream(in));
			result = HttpUtils.changeInputStream(in);
			System.out.println(result);

		}

		if (resEntity != null) {

			resEntity.consumeContent();

		}

		return result;

	}

	/**
	 * 调用系统自带的浏览器打开网页
	 * 
	 * @param url
	 *            要打开的网页
	 * @param context
	 */
	public static void browser(String url, Context context) {
		Intent intent = new Intent();
		intent.setAction("android.intent.action.VIEW");
		Uri content_url = Uri.parse(url);
		intent.setData(content_url);
		context.startActivity(intent);

	}


	/**
	 * 打印日志，调试信息
	 * 
	 * @param info
	 */
	private static void log(String info) {
		// Log.i("HttpUtils", info);
		DebugTools.log("HttpUtils", info);
	}
}
